package limeirafol.bean;

import java.sql.ResultSet;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.List;
import lbframework.classe.Conexao;
import lbframework.classe.Util;
import limeirafol.remote.TipoData;
import limeirafol.remote.cadastro.Situacao;
import limeirafol.remote.venda.OrdemServicoFiltroConsultaVO;
import limeirafol.remote.venda.OrdemServicoVO;
import limeirafol.remote.venda.PedidoFiltroConsultaVO;
import limeirafol.remote.venda.PedidoItemVO;
import limeirafol.remote.venda.PedidoVO;
import limeirafol.remote.venda.SituacaoOrdemServico;
import limeirafol.remote.venda.SituacaoPedido;
import limeirafol.remote.venda.TipoOrdemServico;

public class BeanVenda {

    public PedidoItemVO carregarProduto(int i_id) throws Exception {
        Statement stm = null;
        ResultSet rst = null;
        StringBuilder sql = null;

        stm = Conexao.createStatement();
        sql = new StringBuilder();
        sql.append("SELECT p.precobanho, p.pesototal, p.custofinal, pc.precovenda");
        sql.append(" FROM produto AS p");
        sql.append(" INNER JOIN produtocomplemento AS pc ON pc.id_produto = p.id");
        sql.append(" WHERE p.id = " + i_id + "AND p.id_situacaocadastro = " + Situacao.ATIVO.getId());
        rst = stm.executeQuery(sql.toString());

        PedidoItemVO oItem = new PedidoItemVO();

        if (rst.next()) {
            oItem.precoBanho = rst.getDouble("precobanho");
            oItem.pesoUnitario = rst.getDouble("pesototal");
            oItem.precoCusto = rst.getDouble("custofinal");
            oItem.precoVenda = rst.getDouble("precovenda");

        }

        return oItem;
    }

    public void salvarPedido(PedidoVO i_pedido) throws Exception {
        Statement stm = null;
        ResultSet rst = null;
        StringBuilder sql = null;

        try {
            Conexao.begin();
            stm = Conexao.createStatement();
            //verifica se o produto já está cadastrado
            sql = new StringBuilder();
            sql.append("SELECT * FROM pedido WHERE id = " + i_pedido.numeroPedido);
            rst = stm.executeQuery(sql.toString());

            if (rst.next()) {
                //Global.verificarPermissao(Formulario.PRODUTO, TipoOperacao.ALTERAR);
                sql = new StringBuilder();
                sql.append("UPDATE pedido SET");
                sql.append(" id_os = " + i_pedido.idOS + ", ");
                sql.append(" proforma = " + i_pedido.proforma + ", ");
                sql.append(" invoice = " + i_pedido.invoice + ", ");
                sql.append(" datahorafinalizacao = " + (i_pedido.dataHoraFinalizacao.isEmpty() ? "NULL" : "'" + Util.formatDataHoraBanco(i_pedido.dataHoraFinalizacao) + "'") + ",");
                sql.append(" id_tipofrete = " + i_pedido.idTipoFrete + ", ");
                sql.append(" valorfrete = " + i_pedido.valorFrete + ", ");
                sql.append(" codigorastreamento = '" + i_pedido.codigoRastreamento + "', ");
                sql.append(" custototal = " + i_pedido.custoTotal + ", ");
                sql.append(" totalbanho = " + i_pedido.totalBanho + ", ");
                sql.append(" pesototal = " + i_pedido.pesoTotal + ", ");
                sql.append(" valorouro = " + i_pedido.valorOuro + ", ");
                sql.append(" valortotal = " + i_pedido.valorTotal);
                sql.append(" WHERE id = " + i_pedido.numeroPedido);

                stm.execute(sql.toString());
            } else {
                // Global.verificarPermissao(Formulario.PRODUTO, TipoOperacao.INCLUIR);
                sql = new StringBuilder();
                sql.append("INSERT INTO pedido (id_cliente, datahoraabertura, id_os,");
                sql.append(" proforma, invoice, datahorafinalizacao, id_tipofrete, codigorastreamento, custototal, totalbanho,");
                sql.append(" pesototal, valortotal, valorouro, id_situacaopedido)");
                sql.append(" VALUES (");
                sql.append(i_pedido.idCliente + ", ");
                sql.append("'" + i_pedido.dataHoraAbertura + "', ");
                sql.append(i_pedido.idOS + ", ");
                sql.append(i_pedido.proforma + ", ");
                sql.append(i_pedido.invoice + ", ");
                sql.append((i_pedido.dataHoraFinalizacao.isEmpty() ? "NULL" : "'" + Util.formatDataHoraBanco(i_pedido.dataHoraFinalizacao) + "'") + ", ");
                sql.append(i_pedido.idTipoFrete + ", ");
                sql.append("'" + i_pedido.codigoRastreamento + "', ");
                sql.append(i_pedido.custoTotal + ", ");
                sql.append(i_pedido.totalBanho + ", ");
                sql.append(i_pedido.pesoTotal + ", ");
                sql.append(i_pedido.valorTotal + ", ");
                sql.append(i_pedido.valorOuro + ", ");
                sql.append(i_pedido.idSituacao + ");");

                stm.execute(sql.toString());

                rst = stm.executeQuery("SELECT CURRVAL('pedido_id_seq') AS id");
                rst.next();

                i_pedido.numeroPedido = rst.getInt("id");

            }

            stm.execute("DELETE FROM pedidoitem WHERE id_pedido = " + i_pedido.numeroPedido);

            //salvar itens
            for (PedidoItemVO oItem : i_pedido.vItem) {
                sql = new StringBuilder();
                sql.append("INSERT INTO pedidoitem (id_pedido, id_produto, quantidade, precocusto, precovenda,");
                sql.append(" pesounitario, pesototal, subtotal) VALUES (");
                sql.append(i_pedido.numeroPedido + ", ");
                sql.append(oItem.idProduto + ", ");
                sql.append(oItem.quantidade + ", ");
                sql.append(oItem.precoCusto + ", ");
                sql.append(oItem.precoVenda + ", ");
                sql.append(oItem.pesoUnitario + ", ");
                sql.append(oItem.pesoTotal + ", ");
                sql.append(oItem.subTotal + ")");

                stm.execute(sql.toString());
            }

            stm.close();
            Conexao.commit();

        } catch (Exception ex) {
            Conexao.rollback();
            throw ex;
        }
    }

    public List<PedidoVO> consultarPedido(PedidoFiltroConsultaVO i_filtro) throws Exception {
        Statement stm = null;
        ResultSet rst = null;
        StringBuilder sql = null;

        stm = Conexao.createStatement();

        sql = new StringBuilder();
        sql.append(" SELECT ped.id, ped.datahoraabertura, ped.datahorafinalizacao, c.nome, ped.custototal,");
        sql.append(" (SELECT COUNT(id) ");
        sql.append(" FROM pedidoitem ");
        sql.append(" WHERE id_pedido = ped.id) AS qtdItens,");
        sql.append(" ped.totalbanho, ped.valortotal,");
        sql.append(" ped.invoice, ped.proforma, ped.codigorastreamento, sped.descricao AS situacao");
        sql.append(" FROM pedido AS ped");
        sql.append(" INNER JOIN cliente AS c ON c.id = ped.id_cliente");
        sql.append(" INNER JOIN situacaopedido AS sped ON sped.id = ped.id_situacaopedido");
        sql.append(" WHERE 1 = 1");

        if (!i_filtro.dataInicio.equals("") && !i_filtro.dataTermino.isEmpty()) {
            if (i_filtro.tipoData == TipoData.ABERTURA.getId()) {
                sql.append(" AND ped.datahoraabertura::date BETWEEN '" + Util.formatDataBanco(i_filtro.dataInicio) + "'");
                sql.append(" AND '" + Util.formatDataBanco(i_filtro.dataTermino) + "'");
            } else {
                sql.append(" AND ped.datahorafinalizacao::date BETWEEN '" + Util.formatDataBanco(i_filtro.dataInicio) + "'");
                sql.append(" AND '" + Util.formatDataBanco(i_filtro.dataTermino) + "'");
            }
        }

        if (i_filtro.numeroPedido != 0) {
            sql.append(" AND ped.id = " + i_filtro.numeroPedido);
        }

        if (i_filtro.idCliente > 0) {
            sql.append(" AND ped.id_cliente = " + i_filtro.idCliente);
        }

        if (i_filtro.invoice != 0) {
            sql.append(" AND ped.invoice = " + i_filtro.invoice);
        }

        if (i_filtro.proforma != 0) {
            sql.append(" AND ped.proforma = " + i_filtro.proforma);
        }

        if (!i_filtro.codigoRastreamento.trim().equals("")) {
            sql.append(" AND " + Util.getGoogle("ped.codigorastreamento", i_filtro.codigoRastreamento));
        }

        if (i_filtro.idSituacao != -1) {
            sql.append(" AND ped.id_situacaopedido = " + i_filtro.idSituacao);
        }

        sql.append(" ORDER BY ped.id");

        rst = stm.executeQuery(sql.toString());

        List<PedidoVO> vPedido = new ArrayList();
        while (rst.next()) {
            PedidoVO oPedido = new PedidoVO();
            oPedido.numeroPedido = rst.getInt("id");
            oPedido.dataHoraAbertura = Util.formatDataHoraGUI(rst.getTimestamp("datahoraabertura"));
            oPedido.dataHoraFinalizacao = rst.getDate("datahorafinalizacao") == null ? "" : Util.formatDataHoraGUI(rst.getTimestamp("datahorafinalizacao"));
            oPedido.cliente = rst.getString("nome");
            oPedido.qtdItens = rst.getInt("qtditens");
            oPedido.custoTotal = rst.getDouble("custototal");
            oPedido.totalBanho = rst.getDouble("totalbanho");
            oPedido.valorTotal = rst.getDouble("valortotal");
            oPedido.invoice = rst.getInt("invoice");
            oPedido.proforma = rst.getInt("proforma");
            oPedido.codigoRastreamento = rst.getString("codigorastreamento");
            oPedido.situacao = rst.getString("situacao");

            vPedido.add(oPedido);
        }

        return vPedido;
    }

    public PedidoVO carregarPedido(long i_pedido) throws Exception {
        Statement stm = null;
        ResultSet rst = null;
        StringBuilder sql = null;

        stm = Conexao.createStatement();

        sql = new StringBuilder();
        sql.append("SELECT *");
        sql.append(" FROM pedido");
        sql.append(" WHERE id = " + i_pedido);

        rst = stm.executeQuery(sql.toString());

        PedidoVO oPedido = new PedidoVO();

        if (rst.next()) {
            oPedido.numeroPedido = rst.getLong("id");
            oPedido.idCliente = rst.getInt("id_cliente");
            oPedido.dataHoraAbertura = Util.formatDataHoraGUI(rst.getTimestamp("datahoraabertura"));
            oPedido.idOS = rst.getInt("id_os");
            oPedido.proforma = rst.getInt("proforma");
            oPedido.invoice = rst.getInt("invoice");
            oPedido.dataHoraFinalizacao = rst.getDate("datahorafinalizacao") == null ? "" : Util.formatDataHoraGUI(rst.getTimestamp("datahorafinalizacao"));
            oPedido.idTipoFrete = rst.getInt("id_tipofrete");
            oPedido.valorFrete = rst.getDouble("valorfrete");
            oPedido.codigoRastreamento = rst.getString("codigorastreamento");
            oPedido.idSituacao = rst.getInt("id_situacaopedido");
            oPedido.valorOuro = rst.getDouble("valorouro");
        }

        sql = new StringBuilder();
        sql.append(" SELECT p.id, p.descricao, p.id_tipoproduto, tb.sigla, pedi.quantidade, pedi.precocusto, pedi.precovenda,");
        sql.append(" p.precobanho, pedi.pesounitario, pedi.pesototal, pedi.subtotal");
        sql.append(" FROM pedidoitem AS pedi");
        sql.append(" INNER JOIN produto AS p ON p.id = pedi.id_produto");
        sql.append(" INNER JOIN banho AS tb ON tb.id = p.id_tipobanho");
        sql.append(" WHERE pedi.id_pedido = " + i_pedido);

        rst = stm.executeQuery(sql.toString());
        while (rst.next()) {
            PedidoItemVO oItem = new PedidoItemVO();
            oItem.idProduto = rst.getInt("id");
            oItem.idTipoProduto = rst.getInt("id_tipoproduto");
            oItem.produto = rst.getString("descricao") + " " + rst.getString("sigla");
            oItem.quantidade = rst.getInt("quantidade");
            oItem.precoCusto = rst.getDouble("precocusto");
            oItem.precoVenda = rst.getDouble("precovenda");
            oItem.precoBanho = rst.getDouble("precobanho");
            oItem.pesoUnitario = rst.getDouble("pesounitario");
            oItem.pesoTotal = rst.getDouble("pesototal");
            oItem.subTotal = rst.getDouble("subtotal");

            oPedido.vItem.add(oItem);
        }

        stm.close();
        return oPedido;
    }

    public void gerarOrdemServico(PedidoVO i_pedido) throws Exception {
        Statement stm = null;
        ResultSet rst = null;
        StringBuilder sql = null;

        stm = Conexao.createStatement();

        try {
            Conexao.begin();

            stm.execute("UPDATE pedido SET id_situacaopedido = " + SituacaoPedido.PRODUCAO.getId() + " WHERE id = " + i_pedido.numeroPedido);

            sql = new StringBuilder();

            sql.append("INSERT INTO ordemservico (id_pedido, id_cliente, valorouro, datahoraabertura, id_tipoordemservico, id_situacaoordem) VALUES (");
            sql.append(i_pedido.numeroPedido + ",");
            sql.append(i_pedido.idCliente + ", ");
            sql.append(i_pedido.valorOuro + ", ");
            sql.append("'" + Util.formatDataHoraBanco(Util.getDataHoraAtual()) + "', ");
            sql.append(TipoOrdemServico.PEDIDO.getId() + ", ");
            sql.append(SituacaoOrdemServico.ABERTA.getId() + ");");
            stm.execute(sql.toString());

            rst = stm.executeQuery("SELECT CURRVAL('ordemservico_id_seq') AS id");
            rst.next();

            i_pedido.idOS = rst.getLong("id");

            for (PedidoItemVO oPedidoItem : i_pedido.vItem) {
                sql = new StringBuilder();
                sql.append(" INSERT INTO ordemservicoitem (id_ordemservico, id_produto, quantidade) VALUES (");
                sql.append(i_pedido.idOS + ", ");
                sql.append(oPedidoItem.idProduto + ", ");
                sql.append(oPedidoItem.quantidade + ")");

                stm.execute(sql.toString());
            }

            stm.close();
            Conexao.commit();

            i_pedido.idSituacao = SituacaoPedido.PRODUCAO.getId();

        } catch (Exception ex) {
            Conexao.rollback();
            throw ex;
        }
    }

    public boolean verificaOs(int i_idOs) throws Exception {
        Statement stm = null;
        ResultSet rst = null;

        stm = Conexao.createStatement();

        rst = stm.executeQuery("SELECT id FROM ordemservico WHERE id = " + i_idOs + " AND id_situacaoordem = " + SituacaoOrdemServico.FINALIZADA.getId());

        if (rst.next()) {
            return true;
        } else {
            return false;
        }
    }

    public void finalizarOs(int i_idOs) throws Exception {
        Statement stm = null;

        stm = Conexao.createStatement();

        stm.execute("UPDATE ordemservico SET id_situacaoordem = " + SituacaoOrdemServico.FINALIZADA.getId() + ", datahorafinalizacao = '" + Util.formatDataHoraBanco(Util.getDataHoraAtual()) + "' WHERE id = " + i_idOs);

        stm.close();
    }

    public void cancelarOs(int i_idOs) throws Exception {
        Statement stm = null;

        stm = Conexao.createStatement();

        stm.execute("UPDATE ordemservico SET id_situacaoordem = " + SituacaoOrdemServico.CANCELADA.getId() + " WHERE id = " + i_idOs);

        stm.close();
    }

    public void finalizarPedido(PedidoVO i_pedido) throws Exception {
        Statement stm = null;

        stm = Conexao.createStatement();

        salvarPedido(i_pedido);

        stm.execute("UPDATE pedido SET id_situacaopedido = " + SituacaoPedido.FINALIZADO.getId() + " WHERE id = " + i_pedido.numeroPedido);

        stm.close();
    }

    public void estornarPedido(int i_numeroPedido) throws Exception {
        Statement stm = null;

        stm = Conexao.createStatement();

        stm.execute("UPDATE pedido SET id_situacaopedido = " + SituacaoPedido.PRODUCAO.getId() + ", datahorafinalizacao = NULL WHERE id = " + i_numeroPedido);

        stm.close();
    }

    public void cancelarPedido(int i_numeroPedido) throws Exception {
        Statement stm = null;

        stm = Conexao.createStatement();

        stm.execute("UPDATE pedido SET id_situacaopedido = " + SituacaoPedido.CANCELADO.getId() + " WHERE id = " + i_numeroPedido);

        stm.close();
    }

    public List<OrdemServicoVO> consultarOrdemServico(OrdemServicoFiltroConsultaVO i_filtro) throws Exception {
        Statement stm = null;
        ResultSet rst = null;
        StringBuilder sql = null;

        stm = Conexao.createStatement();

        sql = new StringBuilder();
        sql.append(" SELECT os.id, os.id_cliente, c.nome, os.id_situacaoordem, sos.descricao as situacao,");
        sql.append(" os.id_tipoordemservico, tos.descricao as tipoordemservico, os.datahoraabertura,");
        sql.append(" os.datahorafinalizacao");
        sql.append(" FROM ordemservico as os");
        sql.append(" INNER JOIN cliente as c on c.id = os.id_cliente");
        sql.append(" INNER JOIN situacaoordemservico as sos on sos.id = os.id_situacaoordem");
        sql.append(" INNER JOIN tipoordemservico as tos on tos.id = os.id_tipoordemservico");
        sql.append(" WHERE 1 = 1");

        if (!i_filtro.dataInicio.equals("") && !i_filtro.dataTermino.isEmpty()) {
            if (i_filtro.tipoData == TipoData.ABERTURA.getId()) {
                sql.append(" AND os.datahoraabertura::date BETWEEN '" + Util.formatDataBanco(i_filtro.dataInicio) + "'");
                sql.append(" AND '" + Util.formatDataBanco(i_filtro.dataTermino) + "'");
            } else {
                sql.append(" AND os.datahorafinalizacao::date BETWEEN '" + Util.formatDataBanco(i_filtro.dataInicio) + "'");
                sql.append(" AND '" + Util.formatDataBanco(i_filtro.dataTermino) + "'");
            }
        }

        if (i_filtro.numeroOrdemServico != 0) {
            sql.append(" AND os.id = " + i_filtro.numeroOrdemServico);
        }

        if (i_filtro.idCliente > 0) {
            sql.append(" AND os.id_cliente = " + i_filtro.idCliente);
        }

        if (i_filtro.idTipoOrdem != -1) {
            sql.append(" AND os.id_tipoordemservico = " + i_filtro.idTipoOrdem);
        }

        if (i_filtro.idSituacao != -1) {
            sql.append(" AND os.id_situacaoordem = " + i_filtro.idSituacao);
        }

        sql.append(" ORDER BY os.id");

        rst = stm.executeQuery(sql.toString());

        List<OrdemServicoVO> vOrdemServico = new ArrayList();
        while (rst.next()) {
            OrdemServicoVO oOrdem = new OrdemServicoVO();
            oOrdem.id = rst.getInt("id");
            oOrdem.idCliente = rst.getInt("id_cliente");
            oOrdem.cliente = rst.getString("nome");
            oOrdem.dataHoraAbertura = Util.formatDataHoraGUI(rst.getTimestamp("datahoraabertura"));
            oOrdem.dataHoraFinalizacao = rst.getDate("datahorafinalizacao") == null ? "" : Util.formatDataHoraGUI(rst.getTimestamp("datahorafinalizacao"));
            oOrdem.idSituacao = rst.getInt("id_situacaoordem");
            oOrdem.situacao = rst.getString("situacao");
            oOrdem.idTipoOrdem = rst.getInt("id_tipoordemservico");
            oOrdem.tipoOrdem = rst.getString("tipoordemservico");

            vOrdemServico.add(oOrdem);
        }

        return vOrdemServico;
    }
}
